﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace CDSysLDManageProject
{
    public class MySocket
    {
        public Socket clientSocket;
        //创建客户端

        string IP = System.Configuration.ConfigurationManager.AppSettings["CDIPAddress"];
        int IPPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["CDIPPort"]);
        private static Boolean IsconnectSuccess = false;

        public bool CreateClient(string ip, int ipPort)
        {
            IP = ip;
            IPPort = ipPort;
            return CreateClient();
        }

        public bool CreateClient()
        {
            //设定服务器IP地址  
            IPAddress ip1 = IPAddress.Parse(IP);
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.SendTimeout = 1000;
            try
            {
                clientSocket.Connect(new IPEndPoint(ip1, IPPort)); //配置服务器IP与端口  
                Console.WriteLine("连接服务器成功");
                return true;
            }
            catch
            {
                Console.WriteLine("连接服务器失败，请按回车键退出！");
                return false;
            }
        }



        /// 断线重连函数
        /// 
        /// 
        public bool Reconnect()
        {
            //关闭socket
            clientSocket.Shutdown(SocketShutdown.Both);

            clientSocket.Disconnect(true);
            IsconnectSuccess = false;

            clientSocket.Close();

            //创建socket
            return CreateClient();
        }

        public bool IsSocketConnected()
        {
            #region remarks
            /********************************************************************************************
             * 当Socket.Conneted为false时， 如果您需要确定连接的当前状态，请进行非阻塞、零字节的 Send 调用。
             * 如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035)，则该套接字仍然处于连接状态； 
             * 否则，该套接字不再处于连接状态。
             * Depending on http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connected.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
            ********************************************************************************************/
            #endregion

            #region 过程
            // This is how you can determine whether a socket is still connected.
            bool connectState = true;
            bool blockingState = clientSocket.Blocking;
            try
            {
                byte[] tmp = new byte[1];

                clientSocket.Blocking = false;
                clientSocket.Send(tmp, 0, 0);
                //Console.WriteLine("Connected!");
                connectState = true; //若Send错误会跳去执行catch体，而不会执行其try体里其之后的代码
            }
            catch (SocketException e)
            {
                // 10035 == WSAEWOULDBLOCK
                if (e.NativeErrorCode.Equals(10035))
                {
                    //Console.WriteLine("Still Connected, but the Send would block");
                    connectState = true;
                }

                else
                {
                    //Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
                    connectState = false;
                }
            }
            finally
            {
                clientSocket.Blocking = blockingState;
            }

            //Console.WriteLine("Connected: {0}", client.Connected);
            return connectState;
            #endregion
        }

        public int SocketReceive(List<byte> BufferList)
        {
            try
            {
                if (clientSocket == null)
                {
                    CreateClient();
                }
                else if (!clientSocket.Connected)
                {
                    if (!IsSocketConnected())
                        Reconnect();
                }
                byte[] readBuffer = new byte[65535];
                int bytesRec = clientSocket.Receive(readBuffer);

                if (bytesRec > 0)
                {
                    //  byte[] buffer = new byte[recCount];
                    byte[] buffernew = new byte[bytesRec];
                    Buffer.BlockCopy(readBuffer, 0, buffernew, 0, bytesRec);
                   // Log.WriteLog(LogFile.ReciveFromECS, Encoding.ASCII.GetString(buffernew));//读取记录
                    Log.ReciveFromECS.Add(Encoding.ASCII.GetString(buffernew));
                    lock (BufferList)
                    { 
                        BufferList.AddRange(buffernew);
                    }
                }
                return bytesRec;
            }
            catch (SocketException se)
            {
                //print se.ErrorCode
                Exceptionlog.InsertException(se);
                return 0;
            }
        }

        /// 同步send函数
        /// 
        /// 
        /// 
        public bool SocketSend(byte[] senddata)
        {
            bool result = false;
            if (senddata == null)
            {
                return false;
            }
            if (senddata.Length < 1)
            {
                return false;
            }
            try
            {
                if (clientSocket == null)
                {
                    CreateClient();
                }
                else if (!clientSocket.Connected)
                {
                    if (!IsSocketConnected())
                        Reconnect();
                }
               clientSocket.Send(senddata);
               result = true;
            }
            catch
            {
                result = false;
            }
            return result;
        }
    }
}
